<template>
  <el-col
    v-loading="loading"
    class="ZCTable-wrap"
    :style="{
      width: width,
    }"
  >
    <el-table
      :id="id"
      :ref="refName"
      size="mini"
      :max-height="height"
      :border="border"
      :data="tableData"
      :show-header="showHeader"
      :header-cell-style="getHeaderClass"
      :row-class-name="tableRowClassName"
      :span-method="objectSpanMethod"
      @sort-change="sortChange"
      @select="handleSelectionChange"
      @select-all="handleSelectionChange"
      @expand-change="handleExpandChange"
    >
      <el-table-column v-if="expand" type="expand" width="25">
        <template slot-scope="scope">
          <div :style="expandObj">
            <slot name="expand-slot" :opts="scope.row"></slot>
          </div>
        </template>
      </el-table-column>
      <el-table-column
        v-if="selection"
        fixed="left"
        type="selection"
        align="center"
        width="45"
        :selectable="handleSelectable"
      ></el-table-column>
      <!--            :row-class-name="tableRowClassName"-->
      <el-table-column v-if="orderSwitch" align="center" width="80px">
        <template #header>
          <div align="center" class="headerBox" style="color: #939393">
            {{ $t('index.order') }}
          </div>
        </template>
        <template slot-scope="scope" #content>
          <div
            style="
              color: #939393;
              max-width: 500px;
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-box-orient: vertical;
            "
          >
            {{ scope.$index + 1 }}
          </div>
        </template>
      </el-table-column>
      <!--      表格列循环-->
      <table-header
        v-for="(item, index) in tableColumn"
        :key="index"
        :column-height="columnHeight"
        :data="item"
        :origin-table-data="tableData"
      >
        <template v-slot:row-slot="{ opts }">
          <div v-if="opts">
            <slot name="custom-slot" :opts="opts"></slot>
          </div>
        </template>
      </table-header>
      <el-table-column
        v-if="showHandlerBar"
        :fixed="handlerBarPosition"
        align="center"
        :width="operationWidth"
      >
        <template slot="header">
          <div align="center" class="headerBox" style="color: #606266">
            {{ $t(`index.${operationName}`) }}
          </div>
        </template>
        <template slot-scope="scope">
          <slot name="operation-slot" :opts="scope.row"></slot>
        </template>
      </el-table-column>
    </el-table>
  </el-col>
</template>
<script>
import tableHeader from './ZcTableHeader.vue'

export default {
  name: 'ZcTable',
  components: { tableHeader },
  props: {
    loading: {
      type: Boolean,
      default: false,
    },
    expandObj: {
      type: Object,
      default() {
        return {
          padding: '10px',
          background: 'transparent',
          borderRadius: '10px',
        }
      },
    },
    tableColumn: {
      type: Array,
      default: () => [
        { name: 'test1', value: 'name1', color: '#0DF5F9', negative: false },
        { name: 'test2', value: 'name2', color: 'yellow', negative: false },
        { name: 'test3', value: 'name3', color: 'yellow', negative: false },
      ],
    },
    tableData: {
      type: Array,
      default: () => [],
    },
    expand: {
      type: Boolean,
      default: false,
    },
    expandBackground: {
      type: String,
      default: 'rgb(252 252 252)',
    },
    refName: {
      type: String,
      default: '$ZcTable',
    },
    selection: {
      type: Boolean,
      default: false,
    },
    selectableMethod: {
      type: Function,
      default() {
        return () => {
          return true
        }
      },
    },
    id: {
      type: String,
      default: '',
    },
    border: {
      type: Boolean,
      default: false,
    },
    // eslint-disable-next-line vue/require-prop-type-constructor
    handlerBarPosition: '',
    operationWidth: {
      type: String,
      default: '80px',
    },
    showHandlerBar: {
      type: Boolean,
      default: false,
    },
    // operationMethod: {
    //   type: Function,
    //   default() {
    //     return () => {
    //       alert('handleEdit')
    //     }
    //   },
    // },
    operationName: {
      type: String,
      default: 'Operation',
    },
    zebra: {
      type: Boolean,
      default: false,
    },
    rowClassName: {
      type: String,
      default: '',
    },
    headerStyle: {
      type: String,
      default: '',
    },
    orderSwitch: {
      type: Boolean,
      default: false,
    },
    columnHeight: {
      type: String,
      default: '',
    },
    showHeader: {
      type: Boolean,
      default: true,
    },
    height: {
      type: String,
      default: 'calc(100% - 45px)',
    },
    width: {
      type: String,
      default: '100%',
    },
    mergeRow: {
      type: Boolean,
      default: false,
    },
    extraSpanMethod: {
      type: Function,
      default() {
        return false
      },
    },
    pageCur: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      // loading: false,
      needMergeObj: {},
      needMergeArr: [],
      selectItem: [],
      selectObj: {}, // 已选择的行
    }
  },
  watch: {
    tableData: {
      handler(val) {
        // this.loading = false
        if (this.mergeRow && this.tableData.length > 0) {
          this.getNeedMergeRows()
        }
        if (this.selection) {
          let syncDataFun = () => {
            // 还原 表格 勾选项
            this.$nextTick(() => {
              if (this.$T.isTrue(this.selectObj[this.pageCur])) {
                let dataPre = []
                this.selectObj[this.pageCur].forEach((a) => {
                  this.tableData.forEach((a2, i2, n2) => {
                    if (a2['id'] === a['id']) {
                      this.$refs[this.refName].toggleRowSelection(a2, true)
                      dataPre.push(a2)
                    }
                  })
                })
                this.selectObj[this.pageCur] = dataPre
                this.$emit('handleSelection', this.selectObj)
              }
            })
          }
          // 设置阈值
          let counter = 0
          let getTableLength = () => {
            if (this.tableData.length > 0) {
              syncDataFun()
            } else {
              if (counter < 50) {
                setTimeout(() => {
                  counter++
                  getTableLength()
                }, 300)
              }
            }
          }
          // getTableLength()
        }
      },
      deep: true,
    },
  },
  created() {
    this.getNeedMergeCell()
  },
  methods: {
    syncDataFun() {
      // 还原 表格 勾选项
      if (this.$T.isTrue(this.selectObj[this.pageCur])) {
        let dataPre = []
        this.selectObj[this.pageCur].forEach((a) => {
          this.tableData.forEach((a2, i2, n2) => {
            if (a2['id'] === a['id']) {
              this.$refs[this.refName].toggleRowSelection(a2, true)
              dataPre.push(a2)
            }
          })
        })
        this.selectObj[this.pageCur] = dataPre
        this.$emit('handleSelection', this.selectObj)
      }
    },
    handleExpandChange(row, status) {
      debugger
      this.$emit('handleExpandChange', row, status)
    },
    toggleSelect(row, index, objName) {
      if (this.pageCur != objName) {
        this.selectObj[objName].splice(index, 1)
      } else {
        this.selectObj[objName].forEach((a) => {
          if (a['id'] === row[0]['id']) {
            this.$refs[this.refName].toggleRowSelection(a)
          }
        })
      }
    },
    handleSelectionChange(val, row) {
      this.selectObj[this.pageCur] = val
      this.$emit('handleSelection', this.selectObj, row)
    },
    handleSelectable(row, index) {
      if (this.selection) {
        return this.selectableMethod(row, index)
      }
    },
    sortChange(data) {
      this.$emit('handleOrder', data)
    },
    getNeedMergeCell() {
      this.needMergeArr = []
      let forMethod = (arr) => {
        arr.forEach((a, i, n) => {
          if (a.hasOwnProperty('children')) {
            forMethod(a['children'])
          } else {
            if (a.rowMerge && a.rowMerge === true) {
              this.needMergeArr.push(a.value)
            }
          }
        })
      }
      forMethod(this.tableColumn)
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (this.extraSpanMethod(rowIndex, columnIndex)) {
        return this.extraSpanMethod(rowIndex, columnIndex)
      }
      if (this.needMergeObj[column.property]) {
        return {
          rowspan: this.needMergeObj[column.property][rowIndex],
          colspan: 1,
        }
      }
    },
    getNeedMergeRows() {
      this.needMergeObj = {}
      this.needMergeArr.forEach((item) => {
        let contactDot = 0
        let spanArr = []
        this.tableData.forEach((tableItem, index) => {
          if (index === 0) {
            spanArr.push(1)
          } else {
            if (tableItem[item] === this.tableData[index - 1][item]) {
              spanArr[contactDot] += 1 // 设置一个锚点，下一条与此条相等时+1
              spanArr.push(0)
            } else {
              contactDot = index
              spanArr.push(1)
            }
          }
        })
        this.needMergeObj[item] = spanArr
      })
    },
    tableRowClassName({ row, rowIndex }) {
      if (this.zebra) {
        if (rowIndex % 2 === 1) {
          return ''
        } else {
          return this.rowClassName
        }
      } else {
        return ''
      }
    },
    getHeaderClass() {
      return this.headerStyle
    },
  },
}
</script>
<!--<style>-->
<!--.el-table td.el-table__cell div {-->
<!--  /*min-height: 23px !important;*/-->
<!--}-->
<!--</style>-->
<style lang="less">
.ZCTable-wrap {
  max-width: 100%;
  textarea {
    text-align: center;
  }
  .blue .el-table th {
    background: white;
  }

  .el-table__row > td {
    /* 去除表格线 */
  }
  padding: 0;

  .headerBox {
    line-height: 1.5;
  }
  .tableHighBlue {
    background: rgb(244, 250, 255);
  }
  .tableHighLightBlue {
    background: rgba(244, 250, 255, 0.6);
  }
  .tableHighGrey {
    background: #ebedef4d;
  }
  .tableHighOrange {
    background: #fffaf6;
  }
  .greyTitle {
    background: #909399;
  }
}
</style>
